<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
<meta name="viewport"
      content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">

    <meta name="author" content="kissdata">


    <meta name="subtitle" content="人生笔记">


    <meta name="description" content="南邮计算机学院2021毕业生王鹏的介绍，cs软件工程专业">


    <meta name="keywords" content="wangpeng 王鹏 南邮 南京">


<title>🆗 | Ubuntu 安装xv6 | 王鹏的小岛</title>



    <link rel="icon" href="/myIcon.ico">




    <!-- stylesheets list from _config.yml -->
    
    <link rel="stylesheet" href="/css/style.css">
    



    <!-- scripts list from _config.yml -->
    
    <script src="/js/script.js"></script>
    
    <script src="/js/tocbot.min.js"></script>
    



    
    
        <!-- MathJax配置，可通过单美元符号书写行内公式等 -->
<script type="text/x-mathjax-config">
    MathJax.Hub.Config({
    "HTML-CSS": {
        preferredFont: "TeX",
        availableFonts: ["STIX","TeX"],
        linebreaks: { automatic:true },
        EqnChunk: (MathJax.Hub.Browser.isMobile ? 10 : 50)
    },
    tex2jax: {
        inlineMath: [ ["$", "$"], ["\\(","\\)"] ],
        processEscapes: true,
        ignoreClass: "tex2jax_ignore|dno",
        skipTags: ['script', 'noscript', 'style', 'textarea', 'pre', 'code']
    },
    TeX: {
        equationNumbers: { autoNumber: "AMS" },
        noUndefined: { attributes: { mathcolor: "red", mathbackground: "#FFEEEE", mathsize: "90%" } },
        Macros: { href: "{}" }
    },
    messageStyle: "none"
    });
</script>
<!-- 给MathJax元素添加has-jax class -->
<script type="text/x-mathjax-config">
    MathJax.Hub.Queue(function() {
        var all = MathJax.Hub.getAllJax(), i;
        for(i=0; i < all.length; i += 1) {
            all[i].SourceElement().parentNode.className += ' has-jax';
        }
    });
</script>
<!-- 通过连接CDN加载MathJax的js代码 -->
<script type="text/javascript" async
        src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js?config=TeX-MML-AM_CHTML">
</script>


    


<meta name="generator" content="Hexo 7.0.0"></head>

<body>
    <script>
        // this function is used to check current theme before page loaded.
        (() => {
            const currentTheme = window.localStorage && window.localStorage.getItem('theme') || '';
            const isDark = currentTheme === 'dark';
            const pagebody = document.getElementsByTagName('body')[0]
            if (isDark) {
                pagebody.classList.add('dark-theme');
                // mobile
                document.getElementById("mobile-toggle-theme").innerText = "· Dark"
            } else {
                pagebody.classList.remove('dark-theme');
                // mobile
                document.getElementById("mobile-toggle-theme").innerText = "· Light"
            }
        })();
    </script>

    <div class="wrapper">
        <header>
    <nav class="navbar">
        <div class="container">
            <div class="navbar-header header-logo"><a href="/">侠之大者</a></div>
            <div class="menu navbar-right">
                
                    <a class="menu-item" href="/update/mystate">Career</a>
                
                    <a class="menu-item" href="/category">Legend</a>
                
                    <a class="menu-item" href="/about">Me</a>
                
                <input id="switch_default" type="checkbox" class="switch_default">
                <label for="switch_default" class="toggleBtn"></label>
            </div>
        </div>
    </nav>

    
    <nav class="navbar-mobile" id="nav-mobile">
        <div class="container">
            <div class="navbar-header">
                <div>
                    <a href="/">侠之大者</a><a id="mobile-toggle-theme">·&nbsp;Light</a>
                </div>
                <div class="menu-toggle" onclick="mobileBtn()">&#9776; Menu</div>
            </div>
            <div class="menu" id="mobile-menu">
                
                    <a class="menu-item" href="/update/mystate">Career</a>
                
                    <a class="menu-item" href="/category">Legend</a>
                
                    <a class="menu-item" href="/about">Me</a>
                
            </div>
        </div>
    </nav>

</header>
<script>
    var mobileBtn = function f() {
        var toggleMenu = document.getElementsByClassName("menu-toggle")[0];
        var mobileMenu = document.getElementById("mobile-menu");
        if(toggleMenu.classList.contains("active")){
           toggleMenu.classList.remove("active")
            mobileMenu.classList.remove("active")
        }else{
            toggleMenu.classList.add("active")
            mobileMenu.classList.add("active")
        }
    }
</script>
            <div class="main">
                <div class="container">
    
    
        <div class="post-toc">
    <div class="tocbot-list">
    </div>
    <div class="tocbot-list-menu">
        <a class="tocbot-toc-expand" onclick="expand_toc()">Expand all</a>
        <a onclick="go_top()">Back to top</a>
        <a onclick="go_bottom()">Go to bottom</a>
    </div>
</div>

<script>
    var tocbot_timer;
    var DEPTH_MAX = 6; // 为 6 时展开所有
    var tocbot_default_config = {
        tocSelector: '.tocbot-list',
        contentSelector: '.post-content',
        headingSelector: 'h1, h2, h3, h4, h5',
        orderedList: false,
        scrollSmooth: true,
        onClick: extend_click,
    };

    function extend_click() {
        clearTimeout(tocbot_timer);
        tocbot_timer = setTimeout(function() {
            tocbot.refresh(obj_merge(tocbot_default_config, {
                hasInnerContainers: true
            }));
        }, 420); // 这个值是由 tocbot 源码里定义的 scrollSmoothDuration 得来的
    }

    document.ready(function() {
        tocbot.init(obj_merge(tocbot_default_config, {
            collapseDepth: 1
        }));
    });

    function expand_toc() {
        var b = document.querySelector('.tocbot-toc-expand');
        var expanded = b.getAttribute('data-expanded');
        expanded ? b.removeAttribute('data-expanded') : b.setAttribute('data-expanded', true);
        tocbot.refresh(obj_merge(tocbot_default_config, {
            collapseDepth: expanded ? 1 : DEPTH_MAX
        }));
        b.innerText = expanded ? 'Expand all' : 'Collapse all';
    }

    function go_top() {
        window.scrollTo(0, 0);
    }

    function go_bottom() {
        window.scrollTo(0, document.body.scrollHeight);
    }

    function obj_merge(target, source) {
        for (var item in source) {
            if (source.hasOwnProperty(item)) {
                target[item] = source[item];
            }
        }
        return target;
    }
</script>
    

    
    <article class="post-wrap">
        <header class="post-header">
            <h1 class="post-title">🆗 | Ubuntu 安装xv6</h1>
            
                <div class="post-meta">
                    
                        Author: <a itemprop="author" rel="author" href="/">kissdata</a>
                    

                    
                        <span class="post-time">
                        Date: <a href="#">Dec 12, 2022&nbsp;&nbsp;0:00</a>
                        </span>
                    
                    
                        <span class="post-category">
                    Category:
                            
                                <a href="/categories/Deploy/">Deploy</a>
                            
                        </span>
                    
                </div>
            
        </header>

        <div class="post-content">
            <p>💬 <strong>为什么学这个？</strong></p>
<p>外国名校的cs专业必修课，几乎人人都玩过，我也想玩。</p>
<p>看到有公司（如 <code>smartX</code>）  的 <u> <a target="_blank" rel="noopener" href="https://www.smartx.com/campus/">招聘要求</a></u>写了，说学过这个的面试加分：</p>
<blockquote>
<p>熟悉 Linux 环境下的程序开发；完成过 MIT 6.824，MIT 6.828 等相关课程；有 <code>HDFS</code>、<code>Ceph</code>、<code>GlusterFS</code> 或其他分布式系统的开发经验。</p>
</blockquote>
<p>【环境】Ubuntu 2204</p>
<p>需要命令工具：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">  tool       version</span><br><span class="line"># -- -- -- | -- -- -- #</span><br><span class="line">· Git         2.34(ubuntu自带)</span><br><span class="line">· make        4.3</span><br></pre></td></tr></table></figure>

<h2 id="一、换源"><a href="#一、换源" class="headerlink" title="一、换源"></a>一、换源</h2><p>需要 QEMU，原先配的stju源里面没有。</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">vim /etc/apt/sources.list</span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">复制连接</span></span><br><span class="line">sudo apt-get update</span><br></pre></td></tr></table></figure>

<p>具体源链接内容看源官网。</p>
<h2 id="二、安装"><a href="#二、安装" class="headerlink" title="二、安装"></a>二、安装</h2><p>【step 1 环境】约900M</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">sudo apt-get install git   <span class="comment"># 已有可忽略</span></span><br><span class="line">sudo apt-get install build-essential gdb-multiarch qemu-system-misc </span><br><span class="line">sudo apt-get install gcc-riscv64-linux-gnu binutils-riscv64-linux-gnu </span><br></pre></td></tr></table></figure>

<p>也可以像官网实验教材直接一行命令搞定。</p>
<p>【step 2 源码】git clone 获取</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">git <span class="built_in">clone</span> git://github.com/mit-pdos/xv6-riscv.git</span><br><span class="line">git <span class="built_in">clone</span> http://github.com/mit-pdos/xv6-riscv.git <span class="comment"># 二选一</span></span><br></pre></td></tr></table></figure>

<p>【step 3 编译】直接 <code>make qemu</code> 完事，编译好了就直接在终端命令行界面。</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">xv6 kernel is booting</span><br><span class="line"></span><br><span class="line">hart 2 starting</span><br><span class="line">hart 1 starting</span><br><span class="line">init: starting sh</span><br><span class="line"><span class="meta prompt_">$</span></span><br></pre></td></tr></table></figure>

<p>基本一路顺风，没有问题。</p>
<p>【step 4 退出】先按 <code>Ctrl+a</code> ，再按 <code>c</code> (不需要一直按 <code>Ctrl</code>) ，进入 qemu 管理命令行窗口，输入 <code>q</code> 退出。</p>
<p>或者另外打开一个shell，直接kill qemu进程</p>
<figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">ps -ef|grep qemu-system</span><br><span class="line"><span class="built_in">kill</span> <span class="comment">#pid</span></span><br></pre></td></tr></table></figure>

<p>下次进入直接 <code>make qemu</code> 。</p>
<h3 id="三、已有命令学习"><a href="#三、已有命令学习" class="headerlink" title="三、已有命令学习"></a>三、已有命令学习</h3><p>就是 shell窗口的使用（shell本身也是一个用户进程，不是内核）。</p>
<p>例1：<code>ls</code> 列出当前目录内容</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line">$ <span class="built_in">ls</span></span><br><span class="line">.              1 1 1024</span><br><span class="line">..             1 1 1024</span><br><span class="line">README         2 2 2305</span><br><span class="line"><span class="built_in">cat</span>            2 3 32832</span><br><span class="line"><span class="built_in">echo</span>           2 4 31688</span><br><span class="line">forktest       2 5 15816</span><br><span class="line">grep           2 6 36208</span><br><span class="line">init           2 7 32184</span><br><span class="line"><span class="built_in">kill</span>           2 8 31648</span><br><span class="line"><span class="built_in">ln</span>             2 9 31472</span><br><span class="line"><span class="built_in">ls</span>             2 10 34776</span><br><span class="line"><span class="built_in">mkdir</span>          2 11 31704</span><br><span class="line"><span class="built_in">rm</span>             2 12 31688</span><br><span class="line">sh             2 13 54128</span><br><span class="line">stressfs       2 14 32576</span><br><span class="line">usertests      2 15 180472</span><br><span class="line">grind          2 16 47520</span><br><span class="line"><span class="built_in">wc</span>             2 17 33784</span><br><span class="line">zombie         2 18 31048</span><br><span class="line">console        3 19 0</span><br></pre></td></tr></table></figure>

<p>例2：<code>grep</code> 命令是要对给定的字符串进行模式匹配。</p>
<p><img src="/../image/test/xv6_grep.png"></p>
<blockquote>
<p>注意！视频中用的例子是  <code>grep x &lt; out</code> ，亲测时你会发现什么也没显示，此时千万不要慌，并不是出问题了，只不过 ls 的内容里确实没有带x的行，换个 <code>grep k</code> 就行了 😂</p>
</blockquote>
<h3 id="四、新增命令"><a href="#四、新增命令" class="headerlink" title="四、新增命令"></a>四、新增命令</h3><p>在 <code>user</code> 目录新增 wpsleep.c 文件，固定头文件至少有以下：</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&quot;kernel/types.h&quot;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&quot;kernel/stat.h&quot;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&quot;user/user.h&quot;</span></span></span><br></pre></td></tr></table></figure>

<p>代码写完后，修改 makefile，增加命令</p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">UPROGS=\</span><br><span class="line">	$U/_cat\</span><br><span class="line">	$U/_echo\</span><br><span class="line">	<span class="comment"># ......</span></span><br><span class="line">	$U/_wc\</span><br><span class="line">	$U/_zombie\</span><br><span class="line">	$U/_wpsleep\ <span class="comment"># 个人新增, 大概在第135行</span></span><br><span class="line"></span><br><span class="line"><span class="section">fs.img: mkfs/mkfs README <span class="variable">$(UPROGS)</span></span></span><br><span class="line">	mkfs/mkfs fs.img README <span class="variable">$(UPROGS)</span></span><br></pre></td></tr></table></figure>

<p>【注意】这里的下划线后的取名必须和代码文件名一致。</p>
<p>因为修改过，不能用原先的 <code>make qemu</code> ，需要重新编译，需要先 <code>make clean</code> ，然后再 <code>make qemu</code>。</p>
<p>此时再看当前目录，可以发现新增自定义的两个命令：</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">$ <span class="built_in">ls</span></span><br><span class="line">.              1 1 1024</span><br><span class="line">..             1 1 1024</span><br><span class="line">README         2 2 2305</span><br><span class="line"><span class="built_in">cat</span>            2 3 32832</span><br><span class="line"><span class="built_in">echo</span>           2 4 31688</span><br><span class="line"><span class="comment"># ...... 略</span></span><br><span class="line"><span class="built_in">wc</span>             2 17 33784</span><br><span class="line">zombie         2 18 31048</span><br><span class="line">wpsleep        2 19 31608 <span class="comment"># 新增</span></span><br><span class="line">wpcopy         2 20 31456 <span class="comment"># 新增</span></span><br><span class="line">console        3 21 0</span><br></pre></td></tr></table></figure>

<p>其他shell操作同上，比如想退出重写，就按 <code>Ctrl + a</code>，然后按 <code>c</code> 键。</p>
<h2 id="附-示例"><a href="#附-示例" class="headerlink" title="附 示例"></a>附 示例</h2><p>第一个要写的系统调用程序 copy：</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&quot;kernel/types.h&quot;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&quot;user/user.h&quot;</span></span></span><br><span class="line"></span><br><span class="line"><span class="type">int</span> <span class="title function_">main</span><span class="params">()</span> &#123;</span><br><span class="line">    <span class="type">char</span> buf[<span class="number">64</span>];</span><br><span class="line"></span><br><span class="line">    <span class="keyword">while</span>(<span class="number">1</span>) &#123;</span><br><span class="line">        <span class="type">int</span> n = read(<span class="number">0</span>, buf, <span class="keyword">sizeof</span>(buf)); <span class="comment">// 读入一些数据, 第一个参数0是文件描述符</span></span><br><span class="line">        <span class="keyword">if</span> (n &lt;= <span class="number">0</span>) <span class="keyword">break</span>; </span><br><span class="line">        write(<span class="number">1</span>, buf, n);  <span class="comment">// 处理: 输出. 文件描述符1表示写入</span></span><br><span class="line">        </span><br><span class="line">        <span class="keyword">if</span> (atoi(buf) == <span class="number">666</span>) &#123; <span class="comment">// 如果输入666，复制完后就退出</span></span><br><span class="line">            <span class="built_in">fprintf</span>(<span class="number">2</span>, <span class="string">&quot;copy ok\n&quot;</span>);</span><br><span class="line">            <span class="keyword">break</span>; </span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="built_in">exit</span>(<span class="number">0</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>copy是自己写的函数，read 和 write 是系统调用。</p>
<p>buf 定义成了64，所以read一次最大接收64个。不能写 <code>1+sizeof(buf)</code> ，那样要传入65个进来，会把栈区中的垃圾接收进来，导致异常（栈溢出）。</p>
<p>write那行要增加错误判断。具体系统调用的返回值看 电子教材第二章。</p>
<blockquote>
<p>新手第一次别看错了，讲的1和0 和 while(1)、exit(0) 里的0和1无关。哈哈哈哈哈。</p>
</blockquote>

        </div>

        
            <section class="post-copyright">
                
                
                
                
                     <p class="copyright-item">
                         <span>Slogan:</span>
                         <span>人生三大错觉：我躲得过去，我能反杀，是不是<strong>喜欢我?</strong></span>
                     </p>
                

            </section>
        
        <section class="post-tags">
            <div>
            </div>
            <div>
                <a href="javascript:window.history.back();">back</a>
                <span>· </span>
                <a href="/">home</a>
            </div>
        </section>
        <section class="post-nav">
            
                <a class="prev" rel="prev" href="/2022/12-24/review_stringtail/">\0 的魔法</a>
            
            
            <a class="next" rel="next" href="/2022/11-18/review_goissue2/">go操作一行字符串</a>
            
        </section>


    </article>
</div>

            </div>
            <footer id="footer" class="footer">
    <div class="copyright">
        <span>187-9597-5517 &nbsp; 王鹏 @ <a href="https://cs.njupt.edu.cn/" target="_blank">njupt</a</span>
    </div>
</footer>

    </div>
</body>

</html>